package com.easy.tool.utils.http;

import com.alibaba.fastjson.JSONObject;
import com.easy.tool.anno.BeanDes;
import com.easy.tool.anno.MethodDes;
import com.easy.tool.constant.MediaConstant;
import lombok.SneakyThrows;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;

import java.io.UnsupportedEncodingException;
import java.util.*;

/**
 * @author 高俊
 * @create 2022-05-2022/5/19-10:37
 */
@BeanDes(name = "http请求", des = "实现发送http请求功能，使用的是Apach的HttpClint")
public class HttpClient2 {

    private static Logger logger = Logger.getLogger(HttpClient2.class);

    /**
     * 发送post请求
     * @param url       请求路径
     * @param body      请求体
     * @param head      请求头
     * @param type      请求类型，使用MediaConstant类型常量
     * @return
     */
    @SneakyThrows
    @MethodDes(des = "发送post请求",
            param = {
                    "arg0-> urlC：请求路径",
                    "arg1-> body：请求体Map<String,String>类型",
                    "arg2-> headMap: 请求头map",
                    "arg3-> type：请求类型，使用MediaConstant常量获取类型，例如：application/x-www-form-urlencoded、application/json"})
    public static String sendPost(String url, Map<String,String> body,Map<String,String> head,String type){
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost post = new HttpPost(url);

        // 没有key就添加，有就覆盖
        for (Map.Entry<String, String> entry : head.entrySet()) {
            post.addHeader(entry.getKey(),entry.getValue());
        }

        if (MediaConstant.MEDIA_FORM_URLENCODED.equals(type)){
            post.addHeader("Content-Type","application/x-www-form-urlencoded;charset=UTF-8");
            post = sendFormUrlEncode(body,post);
        }else if (MediaConstant.MEDIA_APPLICATION_JSON.equals(type)){
            post.addHeader("Content-Type","application/json;charset=UTF-8");
            post = sendApplicationJson(body,post);
        }

        logger.debug("[请求地址：" + url +"]");
        logger.debug("[请求参数：" + body + "]");
        logger.debug("[请求头：" + head + "]");

        CloseableHttpResponse response = httpClient.execute(post);
        logger.info("[-----请求成功-----]");
        return EntityUtils.toString(response.getEntity(),"UTF-8");
    }

    @SneakyThrows
    private static HttpPost sendFormUrlEncode(Map<String,String> body,HttpPost post) {
        List<NameValuePair> nameValuePairs = new ArrayList<>();
        for (Map.Entry<String, String> entry : body.entrySet()) {
            nameValuePairs.add(new BasicNameValuePair(entry.getKey(),entry.getValue()));
        }
        post.setEntity(new UrlEncodedFormEntity(nameValuePairs,"UTF-8"));
        return post;
    }
    @SneakyThrows
    private static HttpPost sendApplicationJson(Map<String,String> body,HttpPost post) {
        JSONObject json = new JSONObject();
        for (Map.Entry<String, String> entry : body.entrySet()) {
            json.put(entry.getKey(),entry.getValue());
        }
        System.out.println(JSONObject.toJSONString(json));
        post.setEntity(new StringEntity(JSONObject.toJSONString(json)));
        return post;
    }


    /**
     * 发送get请求
     * @param url   请求地址
     * @param body  请求参数
     * @param head  请求头
     * @return  返回string类型字符串
     */
    @SneakyThrows
    @MethodDes(des = "发送get请求",param = {"arg0-> urlC：请求路径","arg1-> map：请求体map","arg2-> headMap: 请求头map"})
    public static String sendGet(String url, Map<String,String> body,Map<String,String> head){
        // 组装url
        if (body != null && body.size() > 0){
            url += "?";
            Set<Map.Entry<String, String>> entrySet = body.entrySet();
            Iterator<Map.Entry<String, String>> iterator = entrySet.iterator();
            while (iterator.hasNext()){
                Map.Entry<String, String> next = iterator.next();
                url += next.getKey() + "=" + next.getValue();
                if (iterator.hasNext()){
                    url += "&&";
                }
            }
        }
        logger.debug("[请求地址：" + url +"]");
        logger.debug("[请求参数：" + body + "]");
        logger.debug("[请求头：" + head + "]");

        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet get = new HttpGet(url);

        for (Map.Entry<String, String> entry : head.entrySet()) {
            get.addHeader(entry.getKey(),entry.getValue());
        }

        CloseableHttpResponse response = httpClient.execute(get);
        logger.info("[-----请求成功-----]");
        return EntityUtils.toString(response.getEntity(),"UTF-8");
    }
}
